#include "upper_computer.h"
#include "DataCenter.h"
#include "soft_timer.h"

#include "string.h"

#include "cmd_dy.h"


#ifdef _WIN32
#include "Windows.h"
uint32_t get_time(void) {
	SYSTEMTIME time;

	GetSystemTime(&time);

	return time.wMilliseconds;
}
#else
#include <sys/time.h>

uint32_t get_time(void) {
	struct timeval tv;
	gettimeofday(&tv, NULL);
	long milliseconds = tv.tv_sec * 1000 + tv.tv_usec / 1000;

	return milliseconds;
}
#endif



typedef struct {
	uint8_t data[32];
	uint32_t len;
}Frame_t;
Frame_t frame;

uint8_t buffer[][16] = {
	{0xAA, 0x08, 0x01, 0xAD, 0x01, 0x00, 0x00, 0x00, 0x00, 0x61, 0xEB, 0xAA},
	{0xAA, 0x08, 0x01, 0xAD, 0x01, 0x01, 0x00, 0x00, 0x00, 0x62, 0xEB, 0xAA},

	{0xAA, 0x08, 0x01, 0xAC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x60, 0xEB, 0xAA},
	{0xAA, 0x08, 0x01, 0xAC, 0x01, 0x01, 0x00, 0x00, 0x00, 0x61, 0xEB, 0xAA},

	{0xAA, 0x05, 0x01, 0x02, 0x02, 0x01, 0xB5, 0xEB, 0xAA},
	{0xAA, 0x05, 0x01, 0x02, 0x02, 0x00, 0xB4, 0xEB, 0xAA},

	{0xAA, 0x04, 0x01, 0x11, 0x01, 0xC1, 0xEB, 0xAA},
	{0xAA, 0x04, 0x01, 0x11, 0x00, 0xC0, 0xEB, 0xAA},

	{0xAA, 0x08, 0x01, 0xB3, 0x01, 0x01, 0x00, 0x00, 0x00, 0x68, 0xEB, 0xAA},
	{0xAA, 0x08, 0x01, 0xB3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x67, 0xEB, 0xAA},

	{0xAA, 0x06, 0x01, 0x77, 0x02, 0x10, 0x00, 0x3A, 0xEB, 0xAA},
	{0xAA, 0x06, 0x01, 0x77, 0x02, 0x80, 0x00, 0xAA, 0xEB, 0xAA},

	{0xAA, 0x06, 0x01, 0xA3, 0x01, 0x00, 0x32, 0x87, 0xEB, 0xAA},
	{0xAA, 0x06, 0x01, 0xA3, 0x01, 0x01, 0x32, 0x88, 0xEB, 0xAA},
	{0xAA, 0x06, 0x01, 0xA3, 0x01, 0x02, 0x32, 0x89, 0xEB, 0xAA},
	{0xAA, 0x06, 0x01, 0xA3, 0x01, 0x03, 0x32, 0x8A, 0xEB, 0xAA},

	{0xAA, 0x05, 0x01, 0x43, 0x02, 0x80, 0x75, 0xEB, 0xAA},
	{0xAA, 0x05, 0x01, 0x43, 0x02, 0x00, 0xF5, 0xEB, 0xAA},

	{0xAA, 0x04, 0x01, 0x7F, 0x02, 0x30, 0xEB, 0xAA},	// ����

	{0xAA, 0x08, 0x01, 0xB5, 0x01, 0x01, 0x00, 0x00, 0x00, 0x6A, 0xEB, 0xAA},

	{0xBB, 0xEE, 0x01, 0x01, 0x01},

};





DataCenter Center("CENTER");

Account *act_upper;
Account *act_lower;


int UpperCallback(Account* act, Account::EventParams_t* param) {

	return Account::RES_OK;
}


int LowerCallback(Account* act, Account::EventParams_t* param) {

	if (param->event == Account::EVENT_PUBLISH) {
		dy_protocol_handler((uchar *)param->data);
	}

	return Account::RES_OK;
}


void UpperTimerCallback(soft_timer_t* timer) {
	static uchar index = 0;

	memcpy(&frame, buffer[index], sizeof(buffer[0]));
	index = (index + 1) % (sizeof(buffer) / sizeof(buffer[0]));

	act_upper->Commit((void *) &frame, sizeof(Frame_t));
	act_upper->Publisher();
}

void upper_computer_init() {

	int size = (sizeof(buffer) / sizeof(buffer[0]));

	act_upper = new Account("upper", &Center, sizeof(Frame_t));
	act_lower = new Account("lower", &Center, sizeof(Frame_t));

	act_upper->Subscribe("lower");
	act_upper->SetEventCallback(UpperCallback);

	act_lower->Subscribe("upper");
	act_lower->SetEventCallback(LowerCallback);


	soft_timer_init(get_time);
	soft_timer_create(2000, UpperTimerCallback, NULL);

}

void upper_computer_loop() {
	for (;;) {
		soft_timer_handler();

	}
}
